﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;

namespace Windy.Transformations.Test.Samples
{
    public class KochLSystem
    {
        /*
        http://en.wikipedia.org/wiki/Koch_snowflake
        Koch curve

        A variant of the Koch curve which uses only right-angles.
        variables : F
        constants : + −
        start  : F
        rules  : (F → F+F−F−F+F)
        Here, F means "draw forward", + means "turn left 90°", and - means "turn right 90°" (see turtle graphics).
        n = 0: F
        n = 1: F+F-F-F+F
        n = 2: F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F
        n = 3: F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F+ F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F- F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F- F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F+ F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F
         */
        [Fact()]
        public void KochSequence()
        {
            var kochRuleSet = new Transformation<char, char, char>(
                           (c) => c,
                           new TransferTransformRule<char, char>('+'),
                           new TransferTransformRule<char, char>('-'),
                           new ExpandTransformRule<char, char, char>('F', "F+F-F-F+F"),
                           new BlockTransformRule<char>() // Works as a protector that eliminate the unregistered items 
                           );

            string[] statusList = new string[]
            {
                "F",
                "F+F-F-F+F",
                "F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F",
                "F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F+F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F-F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F-F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F+F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F",
            };

            var current = new List<char>("?????" + statusList[0] + "??????");

            for (int fo = 1; fo < statusList.Length; fo++)
            {
                kochRuleSet.ApplyToList(current);
                var currentString = new string(current.ToArray());

                Assert.Equal(statusList[fo], currentString);
            }
        }
    }
}
